﻿using System;
using System.Linq;
using System.Linq.Expressions;

namespace TaskManager.Domain.Repositories
{
    /// <summary>
    /// Abstract repository
    /// </summary>
    /// <typeparam name="TEntity">Entity type</typeparam>
    /// <typeparam name="TKey">Entity key type</typeparam>
    public interface IRepository<TEntity, TKey>
        where TEntity: IEntity<TKey>
    {
        /// <summary>
        /// Returns all available entities
        /// </summary>
        IQueryable<TEntity> All { get; }
        
        /// <summary>
        /// Returns all available entities retrieving related data (eager loading)
        /// </summary>
        /// <param name="includeProperties">Expression that specifies list of properties to load</param>
        /// <returns>Collection of entities</returns>
        IQueryable<TEntity> AllIncluding(params Expression<Func<TEntity, object>>[] includeProperties);
        
        /// <summary>
        /// Searches for the specified entity
        /// </summary>
        /// <param name="id">Entity identifier</param>
        /// <returns>Entity object or null if entity was not found</returns>
        TEntity Find(TKey id);

        /// <summary>
        /// Inserts new entity
        /// </summary>
        /// <param name="entity">Entity</param>
        void Insert(TEntity entity);

        /// <summary>
        /// Updates entity in the database
        /// </summary>
        /// <param name="entity">Entity</param>
        void Update(TEntity entity);

        /// <summary>
        /// Deletes entity
        /// </summary>
        /// <param name="id">Entity identifier</param>
        void Delete(TKey id);
    }
}